package com.mcode.blog.service.impl;

import com.alibaba.fastjson.JSON;
import com.mcode.blog.config.ApiConfig;
import com.mcode.blog.dao.pojo.SysUser;
import com.mcode.blog.exception.LoginException;
import com.mcode.blog.service.LoginService;
import com.mcode.blog.service.SysUserService;
import com.mcode.blog.utils.JWTUtils;
import com.mcode.blog.vo.ErrorCode;
import com.mcode.blog.vo.params.LoginParams;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 登录
     *
     * @param loginParams
     * @return
     */
    @Override
    public String login(LoginParams loginParams) {
        /**
         * 1. 检查参数是否合法
         * 2. 根据用户名和密码去user表中查询 是否存在
         * 3. 如果不存在 登录失败
         * 4. 如果存在 ，使用jwt 生成token 返回给前端
         * 5. token放入redis当中，redis  token：user信息 设置过期时间（相比来说session会给服务器产生压力，这么做也是为了实现jwt的续签）
         *  (登录认证的时候 先认证token字符串是否合法，去redis认证是否存在)
         */
        String account = loginParams.getAccount();
        String password = loginParams.getPassword();
        if (StringUtils.isBlank(account) || StringUtils.isBlank(password)) {
            throw new LoginException(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }

        password = DigestUtils.md5Hex(password + ApiConfig.salt);
        SysUser sysUser = sysUserService.findUser(account, password);
        if (sysUser == null) {
            throw new LoginException(ErrorCode.ACCOUNT_PWD_NOT_EXIST.getCode(), ErrorCode.ACCOUNT_PWD_NOT_EXIST.getMsg());
        }

        String token = JWTUtils.createToken(sysUser.getId());
        stringRedisTemplate.opsForValue().set(ApiConfig.RedisLoginKey + token, JSON.toJSONString(sysUser), 1, TimeUnit.DAYS);
        return token;
    }


    /**
     * 校验token
     *
     * @param token
     * @return
     */
    @Override
    public SysUser checkToken(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }

        // 解析token
        Map<String, Object> stringObjectMap = JWTUtils.checkToken(token);
        // 解析失败
        if (stringObjectMap == null) {
            return null;
        }

        // 解析成功到redis查找
        String userJson = stringRedisTemplate.opsForValue().get(ApiConfig.RedisLoginKey + token);
        if (StringUtils.isBlank(userJson)) {
            return null;
        }

        // 解析sysUser对象
        return JSON.parseObject(userJson, SysUser.class);
    }


    /**
     * 退出
     *
     * @param token
     */
    @Override
    public void logout(String token) {
        stringRedisTemplate.delete(ApiConfig.RedisLoginKey + token);
    }


    /**
     * 注册
     *
     * @param loginParams
     * @return
     */
    @Override
    public String register(LoginParams loginParams) {
        // 判断参数是否空
        String account = loginParams.getAccount();
        String password = loginParams.getPassword();
        String nickname = loginParams.getNickname();

        if (StringUtils.isBlank(account) || StringUtils.isBlank(nickname) || StringUtils.isBlank(password)) {
            throw new LoginException(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMsg());
        }

        // 查询传入账号是否已存在
        SysUser sysUser = sysUserService.findUserByAccount(account);
        if (sysUser != null) {
            throw new LoginException(ErrorCode.ACCOUNT_EXIST.getCode(), ErrorCode.ACCOUNT_EXIST.getMsg());
        }

        // 注册用户
        SysUser registerUser = new SysUser();
        registerUser.setAccount(account);
        registerUser.setPassword(DigestUtils.md5Hex(password+ ApiConfig.salt));
        registerUser.setNickname(nickname);
        registerUser.setCreateDate(System.currentTimeMillis());
        registerUser.setLastLogin(System.currentTimeMillis());
        registerUser.setAvatar("/static/img/logo.90a68ed.png");
        registerUser.setAdmin(1); //1 为true
        registerUser.setDeleted(0); // 0 为false
        registerUser.setSalt("");
        registerUser.setStatus("");
        registerUser.setEmail("");
        sysUserService.save(registerUser);

        // 生成token并存入redis
        String token = JWTUtils.createToken(registerUser.getId());
        stringRedisTemplate.opsForValue().set(ApiConfig.RedisLoginKey + token, JSON.toJSONString(registerUser), 1, TimeUnit.DAYS);

        // 返回token
        return token;
    }

}
